#include "app_buffer.h"
#include "log/log.h"
#include <stdlib.h>
#include <string.h>

static SubBuffer * App_Buffer_SmallBufferInit(int size)
{
    SubBuffer *buf = malloc(sizeof(SubBuffer));
    buf->ptr = malloc(size);
    buf->size = size;
    buf->len = 0;
    return buf;
}

Buffer *App_Buffer_Init(int size)
{
    Buffer *Big_buffer = NULL;
    // 初始化大缓冲区
    Big_buffer = malloc(sizeof(Buffer));
    // 初始化小缓冲区
    Big_buffer->sub_buffer[0] = App_Buffer_SmallBufferInit(size);
    Big_buffer->sub_buffer[1] = App_Buffer_SmallBufferInit(size);
    Big_buffer->write_index = 0;
    Big_buffer->read_index = 1;
    // 初始化互斥锁
    pthread_mutex_unlock(&Big_buffer->Read_Lock);
    pthread_mutex_unlock(&Big_buffer->Write_Lock);
    return Big_buffer;
}

void App_Buffer_close(Buffer *buffer)
{
    // 释放小缓冲区的数据内存
    free(buffer->sub_buffer[0]->ptr);
    free(buffer->sub_buffer[1]->ptr);
    // 释放小缓冲区
    free(buffer->sub_buffer[0]);
    free(buffer->sub_buffer[1]);
    // 释放大缓冲区
    free(buffer);
}

static void App_Buffer_Switch(Buffer *buffer)
{
    // 加写锁
    pthread_mutex_lock(&buffer->Write_Lock);
    int temp = buffer->write_index;
    buffer->write_index = buffer->read_index;
    buffer->read_index = temp;
    pthread_mutex_unlock(&buffer->Write_Lock);
}

int App_Buffer_Write(Buffer *buffer, char *data, int len)
{
    // 获取写的缓冲区
    SubBuffer *w_buffer = buffer->sub_buffer[buffer->write_index];
    // 判断缓冲区是否够用
    if (w_buffer->size - w_buffer->len < len + 1)
    {
        // 当前缓冲区长度不够，切换缓冲区
        App_Buffer_Switch(buffer);
        w_buffer = buffer->sub_buffer[buffer->write_index];
    }
    if (w_buffer->size - w_buffer->len < len + 1)
    {
        // 两个缓冲区都不够，错误返回
        log_error("缓冲区不够");
        return -1;
    }
    // 写入数据长度
    // 加锁
    pthread_mutex_lock(&buffer->Write_Lock);
    w_buffer->ptr[w_buffer->len] = len;
    memcpy(w_buffer->ptr + w_buffer->len + 1, data, len);
    // 更新缓冲区长度
    w_buffer->len += len + 1;
    // 解锁
    pthread_mutex_unlock(&buffer->Write_Lock);
    log_debug("写入缓冲区成功：%.*s", w_buffer->len, w_buffer->ptr);
    return 0;
}

int App_Buffer_Read(Buffer *buffer, char *data, int len)
{
    // 获取读的缓冲区
    SubBuffer *r_buffer = buffer->sub_buffer[buffer->read_index];
    // 判断缓冲区是否有数据
    if (r_buffer->len == 0)
    {
        // 当前缓冲区无数据，切换缓冲区
        App_Buffer_Switch(buffer);
        r_buffer = buffer->sub_buffer[buffer->read_index];
    }
    if (r_buffer->len == 0)
    {
        // 两个缓冲区都不存在数据，错误返回
        log_error("缓冲区无数据");
        return -1;
    }
    pthread_mutex_lock(&buffer->Read_Lock);
    // 获取数据长度
    int lenth = r_buffer->ptr[0];
    // 提取固定长度的数据
    memcpy(data, r_buffer->ptr + 1, lenth);
    // 移动数据到数组头
    memmove(&r_buffer->ptr[0], r_buffer->ptr + lenth + 1, r_buffer->size - r_buffer->len);
    // 更新缓冲区长度
    r_buffer->len -= lenth + 1;
    pthread_mutex_unlock(&buffer->Read_Lock);
    // 判断缓冲区是否为空
    if (r_buffer->len == 0)
    {
        // 切换缓冲区
        App_Buffer_Switch(buffer);
    }
    return lenth;
}
